package org.dtrd.modules.quartz.job;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.common.util.CheckUtil;
import org.dtrd.common.util.DateUtils;
import org.dtrd.common.util.StringUtil;
import org.dtrd.common.util.TimeUtil;
import org.dtrd.config.system.Constant.SignInPlanUsageStatus;
import org.dtrd.modules.achievement.entity.bean.SignInAction;
import org.dtrd.modules.achievement.entity.po.DtrdEntRdSigninPlan;
import org.dtrd.modules.achievement.service.impl.DtrdEntRdSigninPlanServiceImpl;
import org.dtrd.modules.achievement.service.impl.DtrdEntRdSigninRecordServiceImpl;
import org.dtrd.modules.patient.service.impl.DtrdEntRdPatientServiceImpl;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 发送提醒
 *
 * @author 萧
 * @date:2021-09-22 10:18 下午
 **/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
public class SendReminderJob implements Job {

    /**
     * 打卡计划
     */
    @Autowired
    DtrdEntRdSigninPlanServiceImpl signinPlanService;

    /**
     * 打卡记录
     */
    @Autowired
    DtrdEntRdSigninRecordServiceImpl signinRecordService;

    @Autowired
    DtrdEntRdPatientServiceImpl patientService;

    public static final String COUNT = "count";
    public static final String DATE = "date";

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info("SendReminderJob.execute.[context] 发送提醒定时任务开始执行 执行时间 ------  " + DateUtils.formatDateTime() + " ; 上次执行时间：" + context.getPreviousFireTime() + "; 下次执行时间：" + context.getNextFireTime());
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        log.info("SendReminderJob.execute.[context] jobDataMap = " + jobDataMap);
        int count = StringUtil.StrTrimInt(jobDataMap.get(COUNT));
        Object dateObj2 = jobDataMap.get(DATE);
        String today = DateUtils.formatDate();
        log.info("SendReminderJob.execute.[context] jobDataMap.get(COUNT) = " + jobDataMap.get(COUNT) + "; count= " + count + "; dateObj2=" + dateObj2);
        if (count > 0) {
            Object dateObj = jobDataMap.get(DATE);
            if (!Objects.equals(today, dateObj)) {
                count = 0;
            }
        }
        log.info("SendReminderJob.execute.[context] 发送提醒定时任务开始执行  当前次数 ：" + count + "; " + jobDataMap.get(COUNT));
        // 第一次执行查找打卡记录，没有则创建
        if (count == 0) {
            List<DtrdEntRdSigninPlan> allEffectivePlans = signinPlanService.getAllEffectivePlans();
            if (CheckUtil.isNotEmpty(allEffectivePlans)) {
                allEffectivePlans.stream().filter(plan -> plan.getSignInStatus() == SignInPlanUsageStatus.NotStart.getType() || (DateUtils.compareYMD(plan.getSignInStartdate(), new Date()) && plan.getSignInStatus() != SignInPlanUsageStatus.Using.getType()))
                        .forEach(plan -> {
                            plan.setSignInStatus(SignInPlanUsageStatus.Using.getType());
                            signinPlanService.updateById(plan);
                        });
//                allEffectivePlans.stream().map(DtrdEntRdSigninPlan::getPatientId).filter(patientId -> patientId != null && patientId > 0).forEach(patientId -> signinRecordService.initSignInRecord(patientId));

                int currentDayOfWeek = TimeUtil.getInstance().getCurrentDayOfWeek();

                allEffectivePlans.forEach(plan -> {
                    String signinPlan;
                    switch (currentDayOfWeek) {
                        case Calendar.MONDAY:
                            signinPlan = plan.getSignInJsonMonday();
                            break;
                        case Calendar.TUESDAY:
                            signinPlan = plan.getSignInJsonTuesday();
                            break;
                        case Calendar.WEDNESDAY:
                            signinPlan = plan.getSignInJsonWednesday();
                            break;
                        case Calendar.THURSDAY:
                            signinPlan = plan.getSignInJsonThursday();
                            break;
                        case Calendar.FRIDAY:
                            signinPlan = plan.getSignInJsonFriday();
                            break;
                        case Calendar.SATURDAY:
                            signinPlan = plan.getSignInJsonSaturday();
                            break;
                        default:
                            signinPlan = plan.getSignInJsonSunday();
                            break;
                    }
                    // 过滤未配置的打卡项
                    JSONArray jsonArray = JSONUtil.parseArray(signinPlan);
                    List<SignInAction> signInActions = jsonArray.toList(SignInAction.class);
                    List<SignInAction> collect = signInActions.stream().filter(action -> StrUtil.isNotBlank(action.getStarttime())).collect(Collectors.toList());
                    signinPlan = JSONUtil.toJsonStr(collect);
                    signinRecordService.initSignInRecord(plan.getPatientId(), signinPlan, null);
                });
            }
            System.out.println("SendReminderJob.execute allEffectivePlans=" + allEffectivePlans);
            allEffectivePlans.stream().filter(plan -> plan.getSignInStatus() == SignInPlanUsageStatus.NotStart.getType())
                    .forEach(plan -> {
                        plan.setSignInStatus(SignInPlanUsageStatus.Using.getType());
                        System.out.println("SendReminderJob.execute set to using plan=" + plan);
                        signinPlanService.updateById(plan);
                    });
            jobDataMap.put(DATE, today);
        }
        signinRecordService.sendRemindForAll(count == 0);

        signinRecordService.tagUnDoneRecord();

        count++;
        jobDataMap.put(COUNT, count);
//        context.getMergedJobDataMap().put(COUNT, count);
//        context.getMergedJobDataMap().put(COUNT, count);
        log.info("SendReminderJob.execute.[context] 发送提醒执行结束  执行耗时 ： " + "; 执行次数: " + count);
    }
}
